#ifndef GROUP_CORE_H_
#define GROUP_CORE_H_

#include <Basic.hh>
#include "WorkerChain.hh"

//
/**
 * \file GroupCore.hh
 * \author  jsk <jsk.jinsubkim@gmail.com>
 * \version 1.0
 *
 * \class GroupCore GroupCore.hh
 *
 * GroupCoreWorker 클래스가 공유하는 정보를 보관 및 관리한다.
 * 
 * 본래 펙토리(thread pool)가 관리해야하는 정보이지만, 관리의 부담을 
 * 줄이기 위해서 GroupCoreWorker 클래스를 두어서 워커 관리의 일부분을 
 * 스스로 수행하도록 하였다. GroupCoreWorker 클래스가 스스로 어떤 판단을
 * 하기 위해서는 펙토리의 정보가 필요하다. 그렇다고 펙토리의 인스턴스를 
 * 바로 주고 접근하는 것은 이쁘지 않기 때문에 펙토리의 정보를 관리할 
 * 클래스를 따로 분리하여 이 클래스를 GroupCoreWorker 클래스에서 접근할 수 
 * 있도록 하였다.
 */
class GroupCore
{
	friend class FactoryCore;
	
public:
	/**
	 * \name GroupCore
	 * \param AssgnedChain 워커들을 엮는 리스트.
	 */
	GroupCore(Lock* Key, WorkerChain* AssgnedChain);
	
	/**
	 * \name enter
	 * 
	 * 작업에 들어갈 때 호출해서 현재 작업 중인 워커의 개수를 파악한다.
	 * 
	 * \return 
	 * 
	 * 성공할 경우 RETURN_OK, 
	 * 실패할 경우 RETURN_OK가 아닌 값.
	 */
	virtual ResultOf enter();
	
	/**
	 * \name exit
	 * 
	 * 작업이 끝났을 때 호출해서 현재 작업 중인 워커의 개수를 파악한다.
	 * 
	 * \return 
	 * 
	 * 성공할 경우 RETURN_OK, 
	 * 실패할 경우 RETURN_OK가 아닌 값.
	 */
	virtual ResultOf exit();
	
	/**
	 * \name tellWorking
	 * 
	 * 작업중인 워커의 개수를 알려준다.
	 * 
	 * \return 
	 * 
	 * 작업중인 워커의 개수.
	 */
	virtual USNumber tellWorking();
	
	/**
	 * \name tellAvailable
	 * 
	 * 가용한 워커의 개수를 알려준다.
	 * 
	 * \return 
	 * 
	 * 가용한 워커의 개수.
	 */
	virtual USNumber tellAvailable();
	
	/**
	 * \name tellNumOfCompletedTasks
	 * 
	 * 완료된 작업의 수.
	 * 
	 * \return 
	 * 
	 * 성공할 경우 RETURN_OK, 
	 * 실패할 경우 RETURN_OK가 아닌 값.
	 */
	virtual USNumber tellNumOfCompletedTasks();
	
	/**
	 * \name tellMinWorker
	 * 
	 * 최소 워커의 개수를 알려준다.
	 * 
	 * \return 
	 * 
	 * 최소 워커의 개수.
	 */
	virtual USNumber tellMin();
	
	/**
	 * \name tellMaxWorker
	 * 
	 * 최대 워커의 개수를 알려준다.
	 * 
	 * \return 
	 * 
	 * 최대 워커의 개수.
	 */
	virtual USNumber tellMax();
	
// friend only
	/**
	 * \name setMinWorker
	 * \param NumOfWorker 최소 워커(Worker)의 개수.
	 * 
	 * 최소 워커의 개수를 설정한다.
	 * 
	 * \return 
	 * 
	 * 성공할 경우 RETURN_OK, 
	 * 실패할 경우 RETURN_OK가 아닌 값.
	 */
	virtual ResultOf setMin(USNumber NumOfWorker);
	
	/**
	 * \name setMaxWorker
	 * \param NumOfWorker 최대 워커(Worker)의 개수.
	 * 
	 * 최대 워커의 개수를 설정한다.
	 * 
	 * \return 
	 * 
	 * 성공할 경우 RETURN_OK, 
	 * 실패할 경우 RETURN_OK가 아닌 값.
	 */
	virtual ResultOf setMax(USNumber NumOfWorker);
	
// Member
public:
	/**
	 * 그룹에 참여한 워커들의 리스트.
	 */
	WorkerChain* ListOfWorker;
	
// Member
protected:
	/**
	 * 작업 중인 워커의 개수를 보호하는 락.
	 */
	Lock* LockOfWorkingCount;
	
	/**
	 * 작업 횟수.
	 */
	USNumber WorkCount;
	
	/**
	 * 작업 중인 워커의 수.
	 */
	USNumber NumOfWorkingWorker;
	
	/**
	 * 최소 워커 개수.
	 */
	USNumber MinNumOfWorker;
	
	/**
	 * 최대 워커 개수.
	 */
	USNumber MaxNumOfWorker;
	
	/**
	 * 인스턴스의 상태를 나타낸다.
	 * TRUE일 경우 정상, FALSE일 경우 비정상.
	 */
	bool State;
};

#endif //GROUP_CORE_H_